# coding=utf-8
"""
author: jamon
"""
import asyncio
import traceback
from typing import List

import pygame
import sys

from pygame.event import Event

from client.model.gate_data import GateData
from client.model.global_data import GlobalData
from client.net.conn_manager import NetConnectManager, send_msg_serialize
from client.views.base import ScreenBase, register_screen
from client.views.scene_mgr import scene_mgr
from client.config import ClientConfig
from pygame.surface import Surface

from obespoir.share.espoir_log import global_log as logger

from package.msg_const import MsgID
from server.service.room.base_room import GameType

_need_reload = True


def enter_local_mode():
    local_user_id = 1
    GlobalData().user_id = local_user_id
    GlobalData().set_team_users(
        [{"user_id": local_user_id, "user_name": "test"}])
    GateData().is_net_mode = False
    scene_mgr.switch_to_scene("battle", mode=False, gate_id=1)


def enter_multi_mode():
    GateData().is_net_mode = True
    NetConnectManager().init_connect(host="127.0.0.1", port=11000)
    asyncio.ensure_future(NetConnectManager().start(callback=join_new_game))


def join_new_game():
    try:
        data = {"user_name": GlobalData().user_name,
                "passwd": GlobalData().password}
        send_msg_serialize([
            NetConnectManager().send_message(MsgID.LOGIN, data),
            NetConnectManager().send_message(MsgID.ENTER_MATCH_ROOM,
                                             {"game_type": GameType.DOUBLE}),
            NetConnectManager().send_message(MsgID.SET_READY, {})
        ])
    except Exception:  # noqa
        logger.error(traceback.format_exc())
        logger.error("join_new_game error")


@register_screen("begin")
class BeginScene(ScreenBase):

    def __init__(self, screen: Surface):
        super(BeginScene, self).__init__(screen=screen)
        self.config = ClientConfig()
        self.background_img: Surface = pygame.image.load(
            self.config.background_image_path)
        self.logo_img: Surface = pygame.image.load(self.config.logo_image)

        rgb_white = (255, 255, 255)
        rgb_red = (255, 0, 0)
        self.font = pygame.font.Font(
            self.config.font_path, self.config.width // 12)
        self.player_unselect_1 = self.font.render("1 PLAYER", True, rgb_white)
        self.player_selected_1 = self.font.render("1 PLAYER", True, rgb_red)

        self.player_unselect_2 = self.font.render("2 PLAYER", True, rgb_white)
        self.player_selected_2 = self.font.render("2 PLAYER", True, rgb_red)

        self.tank_cursor: Surface = pygame.image.load(
            self.config.tank_cursor_image).convert_alpha().subsurface(
            (0, 144), (48, 48))

        width, height = self.config.width, self.config.height
        self.logo_img = pygame.transform.scale(
            self.logo_img, (int(width * 0.7), int(height * 0.15)))
        self.is_multi_mode = False

        self.player_rect_1: pygame.Rect = self.player_unselect_1.get_rect()
        self.player_rect_1.left, self.player_rect_1.top = \
            (width - self.player_rect_1.width) / 2, \
            (height - self.player_rect_1.height) / 2
        self.player_rect_2: pygame.Rect = self.player_unselect_2.get_rect()
        self.player_rect_2.left, self.player_rect_2.top = \
            self.player_rect_1.left, self.player_rect_1.bottom + 10

        self.cursor_rect: pygame.Rect = self.tank_cursor.get_rect()
        self.is_selected = False

    def init_screen(self, *args, **kwargs):
        pass

    async def update(self, events: List[Event] = None, **kwargs):
        if events is None:
            events = []
        for event in events:
            if pygame.QUIT == event.type:
                pygame.quit()
                sys.exit()
            elif pygame.KEYUP == event.type:
                if pygame.K_RETURN == event.key:
                    self.is_selected = True
                elif event.key in [pygame.K_UP, pygame.K_DOWN]:
                    self.is_multi_mode = not self.is_multi_mode

        self._screen.blit(self.background_img, (0, 0))
        self._screen.blit(self.logo_img, (100, 100))

        if self.is_multi_mode:
            self._screen.blit(self.player_unselect_1, self.player_rect_1)
            self._screen.blit(self.player_selected_2, self.player_rect_2)
            self.cursor_rect.right = self.player_rect_2.left - 10
            self.cursor_rect.top = self.player_rect_2.top
        else:
            self._screen.blit(self.player_selected_1, self.player_rect_1)
            self._screen.blit(self.player_unselect_2, self.player_rect_2)
            self.cursor_rect.right = self.player_rect_1.left - 10
            self.cursor_rect.top = self.player_rect_1.top
        self._screen.blit(self.tank_cursor, self.cursor_rect)
        if self.is_selected:
            self.switch_other_screen(mode=self.is_multi_mode)
        await asyncio.sleep(0.01)

    def switch_other_screen(self, mode: bool):
        if self.is_changing_scene:
            return
        self.is_changing_scene = True
        logger.info("start", mode=mode)
        if mode:
            # 多人模式，联网
            enter_multi_mode()
        else:
            # 单人模式，本地
            enter_local_mode()
